import UIKit

public class CodeHighlighter {
    // MARK: - Language Support
    public enum Language: String {
        case swift
        case python
        case javascript
        case typescript
        case java
        case kotlin
        case ruby
        case go
        case rust
        case cpp
        case csharp
        case php
        case html
        case css
        case json
        case xml
        case yaml
        case markdown
        case sql
        case shell
        case plaintext
        
        public var displayName: String {
            switch self {
            case .swift: return "Swift"
            case .python: return "Python"
            case .javascript: return "JavaScript"
            case .typescript: return "TypeScript"
            case .java: return "Java"
            case .kotlin: return "Kotlin"
            case .ruby: return "Ruby"
            case .go: return "Go"
            case .rust: return "Rust"
            case .cpp: return "C++"
            case .csharp: return "C#"
            case .php: return "PHP"
            case .html: return "HTML"
            case .css: return "CSS"
            case .json: return "JSON"
            case .xml: return "XML"
            case .yaml: return "YAML"
            case .markdown: return "Markdown"
            case .sql: return "SQL"
            case .shell: return "Shell"
            case .plaintext: return "Plain Text"
            }
        }
    }
    
    // MARK: - Token Types
    private enum TokenType {
        case keyword
        case string
        case number
        case comment
        case type
        case function
        case property
        case `operator`
        case identifier
        case punctuation
        case whitespace
    }
    
    // MARK: - Properties
    private let theme: CodeHighlightTheme
    
    // MARK: - Initialization
    public init(theme: CodeHighlightTheme = DefaultCodeHighlightTheme()) {
        self.theme = theme
    }
    
    // MARK: - Public Methods
    public func highlight(code: String, language: String) -> NSAttributedString {
        let lang = Language(rawValue: language.lowercased()) ?? .plaintext
        let tokens = tokenize(code: code, language: lang)
        return attributedString(from: tokens)
    }
    
    // MARK: - Private Methods
    private func tokenize(code: String, language: Language) -> [(String, TokenType)] {
        var tokens: [(String, TokenType)] = []
        
        // Split code into lines
        let lines = code.components(separatedBy: .newlines)
        
        for (index, line) in lines.enumerated() {
            // Tokenize each line based on language
            let lineTokens = tokenizeLine(line, language: language)
            tokens.append(contentsOf: lineTokens)
            
            // Add newline token except for the last line
            if index < lines.count - 1 {
                tokens.append(("\n", .whitespace))
            }
        }
        
        return tokens
    }
    
    private func tokenizeLine(_ line: String, language: Language) -> [(String, TokenType)] {
        var tokens: [(String, TokenType)] = []
        var currentToken = ""
        var inString = false
        var inComment = false
        var stringDelimiter: Character = "\""
        var inMultilineComment = false
        
        // Get language-specific patterns
        let patterns = getPatterns(for: language)
        
        // Process each character
        let characters = Array(line)
        var i = 0
        while i < characters.count {
            let char = characters[i]
            
            // Handle string literals
            if (char == "\"" || char == "'" || char == "`") && !inComment && !inMultilineComment {
                if inString {
                    if char == stringDelimiter {
                        currentToken += String(char)
                        tokens.append((currentToken, .string))
                        currentToken = ""
                        inString = false
                    } else {
                        currentToken += String(char)
                    }
                } else {
                    if !currentToken.isEmpty {
                        tokens.append((currentToken, determineTokenType(currentToken, patterns: patterns)))
                        currentToken = ""
                    }
                    currentToken += String(char)
                    inString = true
                    stringDelimiter = char
                }
                i += 1
                continue
            }
            
            // Handle escaped characters in strings
            if inString && char == "\\" && i + 1 < characters.count {
                currentToken += String(char) + String(characters[i + 1])
                i += 2
                continue
            }
            
            // Handle comments
            if !inString {
                if !inComment && !inMultilineComment && i + 1 < characters.count {
                    if char == "/" && characters[i + 1] == "/" {
                        if !currentToken.isEmpty {
                            tokens.append((currentToken, determineTokenType(currentToken, patterns: patterns)))
                            currentToken = ""
                        }
                        currentToken = String(line[line.index(line.startIndex, offsetBy: i)...])
                        tokens.append((currentToken, .comment))
                        break
                    } else if char == "/" && characters[i + 1] == "*" {
                        if !currentToken.isEmpty {
                            tokens.append((currentToken, determineTokenType(currentToken, patterns: patterns)))
                            currentToken = ""
                        }
                        inMultilineComment = true
                        i += 2
                        continue
                    }
                } else if inMultilineComment && i + 1 < characters.count {
                    if char == "*" && characters[i + 1] == "/" {
                        inMultilineComment = false
                        i += 2
                        continue
                    }
                }
            }
            
            // Handle whitespace
            if char.isWhitespace && !inString && !inComment && !inMultilineComment {
                if !currentToken.isEmpty {
                    tokens.append((currentToken, determineTokenType(currentToken, patterns: patterns)))
                    currentToken = ""
                }
                tokens.append((String(char), .whitespace))
                i += 1
                continue
            }
            
            // Handle operators and punctuation
            if !inString && !inComment && !inMultilineComment && isOperatorOrPunctuation(char) {
                if !currentToken.isEmpty {
                    tokens.append((currentToken, determineTokenType(currentToken, patterns: patterns)))
                    currentToken = ""
                }
                tokens.append((String(char), .operator))
                i += 1
                continue
            }
            
            if inMultilineComment {
                currentToken += String(char)
                if currentToken.count >= 50 {
                    tokens.append((currentToken, .comment))
                    currentToken = ""
                }
            } else if !inComment {
                currentToken += String(char)
            }
            
            i += 1
        }
        
        // Add any remaining token
        if !currentToken.isEmpty {
            if inMultilineComment {
                tokens.append((currentToken, .comment))
            } else if !inComment {
                tokens.append((currentToken, determineTokenType(currentToken, patterns: patterns)))
            }
        }
        
        return tokens
    }
    
    private func getPatterns(for language: Language) -> [TokenType: Set<String>] {
        switch language {
        case .swift:
            return [
                .keyword: Set(["class", "struct", "enum", "protocol", "extension", "func", "var", "let", "if", "else", "guard", "return", "true", "false", "nil", "self", "super", "init", "deinit", "get", "set", "willSet", "didSet", "throws", "rethrows", "throw", "try", "catch", "as", "is", "switch", "case", "default", "break", "continue", "fallthrough", "where", "while", "for", "in", "repeat", "do", "catch", "import", "typealias", "associatedtype", "operator", "precedencegroup", "public", "private", "internal", "fileprivate", "open", "final", "static", "lazy", "mutating", "nonmutating", "convenience", "required", "override", "weak", "unowned", "inout", "some", "any", "async", "await"]),
                .type: Set(["String", "Int", "Double", "Float", "Bool", "Character", "Array", "Dictionary", "Set", "Optional", "Result", "Error", "Void", "Any", "AnyObject", "Never", "Int8", "Int16", "Int32", "Int64", "UInt", "UInt8", "UInt16", "UInt32", "UInt64", "Float80", "Decimal", "Data", "Date", "URL", "UUID", "Codable", "Encodable", "Decodable", "Hashable", "Equatable", "Comparable", "Sequence", "Collection"]),
                .property: Set(["count", "isEmpty", "first", "last", "description", "hashValue", "startIndex", "endIndex", "indices", "keys", "values", "bytes", "characters", "utf8", "utf16", "unicodeScalars", "localizedDescription", "debugDescription"])
            ]
        case .python:
            return [
                .keyword: Set(["def", "class", "if", "else", "elif", "while", "for", "in", "try", "except", "finally", "with", "as", "assert", "break", "continue", "del", "global", "import", "lambda", "pass", "raise", "return", "yield", "None", "True", "False", "and", "or", "not", "is", "from", "nonlocal", "async", "await", "match", "case", "type", "self", "cls", "property", "staticmethod", "classmethod", "abstractmethod", "super"]),
                .type: Set(["str", "int", "float", "bool", "list", "dict", "set", "tuple", "object", "bytes", "bytearray", "complex", "frozenset", "range", "slice", "memoryview", "type", "Exception", "BaseException", "ArithmeticError", "AssertionError", "AttributeError", "Exception", "ImportError", "IndexError", "KeyError", "NameError", "RuntimeError", "SyntaxError", "TypeError", "ValueError"]),
                .property: Set(["__init__", "__str__", "__len__", "__dict__", "__class__", "__name__", "__doc__", "__module__", "__bases__", "__file__", "__all__", "__iter__", "__next__", "__enter__", "__exit__", "__get__", "__set__", "__delete__", "__call__", "__getitem__", "__setitem__", "__delitem__"])
            ]
        case .javascript:
            return [
                .keyword: Set(["function", "var", "let", "const", "if", "else", "for", "while", "do", "switch", "case", "break", "continue", "return", "try", "catch", "finally", "throw", "class", "extends", "new", "this", "super", "import", "export", "default", "null", "undefined", "true", "false", "typeof", "instanceof", "void", "delete", "in", "of", "async", "await", "yield", "static", "get", "set", "constructor", "prototype", "debugger"]),
                .type: Set(["Array", "Object", "String", "Number", "Boolean", "Function", "Promise", "Map", "Set", "Symbol", "Date", "RegExp", "Error", "BigInt", "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array", "ArrayBuffer", "SharedArrayBuffer", "Atomics", "DataView", "JSON", "Math", "Reflect", "Proxy"]),
                .property: Set(["length", "prototype", "constructor", "name", "arguments", "caller", "apply", "bind", "call", "toString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable"])
            ]
        case .typescript:
            return [
                .keyword: Set(["function", "var", "let", "const", "if", "else", "for", "while", "do", "switch", "case", "break", "continue", "return", "try", "catch", "finally", "throw", "class", "extends", "new", "this", "super", "import", "export", "default", "null", "undefined", "true", "false", "typeof", "instanceof", "void", "delete", "in", "of", "async", "await", "yield", "static", "get", "set", "constructor", "interface", "type", "namespace", "enum", "declare", "abstract", "implements", "private", "protected", "public", "readonly", "as", "is", "keyof", "typeof", "unique", "unknown", "never", "satisfies"]),
                .type: Set(["string", "number", "boolean", "any", "void", "never", "object", "symbol", "bigint", "undefined", "null", "Array", "ReadonlyArray", "Partial", "Required", "Readonly", "Pick", "Record", "Exclude", "Extract", "NonNullable", "Parameters", "ConstructorParameters", "ReturnType", "InstanceType", "ThisParameterType", "OmitThisParameter", "ThisType"]),
                .property: Set(["length", "prototype", "constructor", "name", "arguments", "caller", "apply", "bind", "call", "toString", "valueOf"])
            ]
        case .java:
            return [
                .keyword: Set(["abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", "for", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while", "true", "false", "null"]),
                .type: Set(["String", "Integer", "Long", "Double", "Float", "Boolean", "Character", "Byte", "Short", "Object", "Class", "Throwable", "Exception", "Error", "RuntimeException", "System", "Thread", "Runnable", "Comparable", "Cloneable", "Iterable", "Collection", "List", "Set", "Map", "Queue", "Stack"]),
                .property: Set(["length", "size", "equals", "hashCode", "toString", "clone", "getClass", "wait", "notify", "notifyAll"])
            ]
        case .kotlin:
            return [
                .keyword: Set(["fun", "val", "var", "if", "else", "when", "for", "while", "do", "break", "continue", "return", "try", "catch", "finally", "throw", "class", "interface", "object", "companion", "data", "sealed", "enum", "override", "abstract", "private", "protected", "public", "internal", "import", "package", "this", "super", "null", "true", "false", "is", "in", "by", "lateinit", "init", "constructor", "suspend", "coroutine", "inline", "reified", "crossinline", "noinline", "tailrec", "operator", "infix"]),
                .type: Set(["String", "Int", "Long", "Double", "Float", "Boolean", "Char", "Byte", "Short", "Unit", "Nothing", "Any", "Array", "List", "Set", "Map", "Sequence", "Pair", "Triple", "Result", "Throwable", "Exception", "Error", "Collection", "Iterable", "Iterator", "Comparable", "Lazy", "Deferred", "Job", "Flow"]),
                .property: Set(["size", "length", "indices", "lastIndex", "first", "last", "isEmpty", "isNotEmpty", "keys", "values", "entries"])
            ]
        case .html:
            return [
                .keyword: Set(["html", "head", "body", "div", "span", "p", "a", "img", "ul", "ol", "li", "table", "tr", "td", "th", "form", "input", "button", "select", "option", "textarea", "script", "style", "link", "meta", "title", "h1", "h2", "h3", "h4", "h5", "h6", "header", "footer", "nav", "main", "section", "article", "aside", "figure", "figcaption", "video", "audio", "source", "canvas", "svg", "path", "rect", "circle", "line", "polyline", "polygon"]),
                .type: Set(["id", "class", "style", "href", "src", "alt", "width", "height", "type", "value", "name", "placeholder", "required", "disabled", "checked", "selected", "readonly", "maxlength", "minlength", "pattern", "title", "target", "rel", "method", "action", "enctype", "role", "aria-label", "data-"]),
                .property: Set(["margin", "padding", "border", "width", "height", "color", "background", "font", "text-align", "display", "position", "top", "right", "bottom", "left", "float", "clear", "overflow", "z-index", "opacity"])
            ]
        case .css:
            return [
                .keyword: Set(["@media", "@import", "@keyframes", "@font-face", "@supports", "@page", "@charset", "@namespace", "@counter-style", "@document", "@viewport", "@-webkit-keyframes", "@-moz-keyframes", "@-o-keyframes", "from", "to", "and", "or", "not", "only", "screen", "print", "speech", "all", "hover", "active", "focus", "visited", "first-child", "last-child", "nth-child", "nth-of-type", "first-of-type", "last-of-type", "empty", "target", "enabled", "disabled", "checked", "root", "before", "after"]),
                .type: Set(["px", "em", "rem", "vh", "vw", "vmin", "vmax", "%", "auto", "none", "hidden", "visible", "scroll", "fixed", "absolute", "relative", "static", "block", "inline", "inline-block", "flex", "grid", "table", "inherit", "initial", "unset", "transparent", "currentColor"]),
                .property: Set(["margin", "padding", "border", "width", "height", "color", "background", "font", "text-align", "display", "position", "top", "right", "bottom", "left", "float", "clear", "overflow", "z-index", "opacity", "transform", "transition", "animation", "box-shadow", "text-shadow", "border-radius", "flex", "grid", "gap", "column", "row", "align", "justify", "order"])
            ]
        default:
            return [:]
        }
    }
    
    private func determineTokenType(_ token: String, patterns: [TokenType: Set<String>]) -> TokenType {
        // Check if it's a keyword
        if patterns[.keyword]?.contains(token) == true {
            return .keyword
        }
        
        // Check if it's a type
        if patterns[.type]?.contains(token) == true {
            return .type
        }
        
        // Check if it's a property
        if patterns[.property]?.contains(token) == true {
            return .property
        }
        
        // Check if it's a number
        if token.first?.isNumber == true {
            return .number
        }
        
        // Default to identifier
        return .identifier
    }
    
    private func isOperatorOrPunctuation(_ char: Character) -> Bool {
        let operatorsAndPunctuation = Set("=+-*/<>(){}[],.;:!@#$%^&|\\")
        return operatorsAndPunctuation.contains(char)
    }
    
    private func attributedString(from tokens: [(String, TokenType)]) -> NSAttributedString {
        let result = NSMutableAttributedString()
        
        for (text, type) in tokens {
            let attributes = attributesForTokenType(type)
            let attributedToken = NSAttributedString(string: text, attributes: attributes)
            result.append(attributedToken)
        }
        
        return result
    }
    
    private func attributesForTokenType(_ type: TokenType) -> [NSAttributedString.Key: Any] {
        var attributes: [NSAttributedString.Key: Any] = [
            .font: theme.font
        ]
        
        switch type {
        case .keyword:
            attributes[.foregroundColor] = theme.keywordColor
        case .string:
            attributes[.foregroundColor] = theme.stringColor
        case .number:
            attributes[.foregroundColor] = theme.numberColor
        case .comment:
            attributes[.foregroundColor] = theme.commentColor
            attributes[.font] = theme.font.italics()
        case .type:
            attributes[.foregroundColor] = theme.typeColor
        case .function:
            attributes[.foregroundColor] = theme.functionColor
        case .property:
            attributes[.foregroundColor] = theme.propertyColor
        case .operator:
            attributes[.foregroundColor] = theme.operatorColor
        case .identifier:
            attributes[.foregroundColor] = theme.identifierColor
        case .punctuation:
            attributes[.foregroundColor] = theme.punctuationColor
        case .whitespace:
            attributes[.foregroundColor] = theme.defaultColor
        }
        
        return attributes
    }
}

// MARK: - Font Extension
extension UIFont {
    func italics() -> UIFont {
        return with(.traitItalic)
    }
    
    func bold() -> UIFont {
        return with(.traitBold)
    }
    
    func with(_ traits: UIFontDescriptor.SymbolicTraits) -> UIFont {
        guard let descriptor = fontDescriptor.withSymbolicTraits(traits) else {
            return self
        }
        return UIFont(descriptor: descriptor, size: 0)
    }
}

// MARK: - Code Highlight Theme Protocol
public protocol CodeHighlightTheme {
    var font: UIFont { get }
    var defaultColor: UIColor { get }
    var backgroundColor: UIColor { get }
    var keywordColor: UIColor { get }
    var stringColor: UIColor { get }
    var numberColor: UIColor { get }
    var commentColor: UIColor { get }
    var typeColor: UIColor { get }
    var functionColor: UIColor { get }
    var propertyColor: UIColor { get }
    var operatorColor: UIColor { get }
    var identifierColor: UIColor { get }
    var punctuationColor: UIColor { get }
}

// MARK: - Default Theme Implementation
public struct DefaultCodeHighlightTheme: CodeHighlightTheme {
    public var font: UIFont = .monospacedSystemFont(ofSize: 14, weight: .regular)
    
    public var defaultColor: UIColor {
        if #available(iOS 13.0, *) {
            return .label
        } else {
            return .black
        }
    }
    
    public var backgroundColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemBackground
        } else {
            return .white
        }
    }
    
    public var keywordColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemPink
        } else {
            return UIColor(red: 249/255, green: 38/255, blue: 114/255, alpha: 1.0)
        }
    }
    
    public var stringColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemGreen
        } else {
            return UIColor(red: 166/255, green: 226/255, blue: 46/255, alpha: 1.0)
        }
    }
    
    public var numberColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemOrange
        } else {
            return UIColor(red: 253/255, green: 151/255, blue: 31/255, alpha: 1.0)
        }
    }
    
    public var commentColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemGray
        } else {
            return UIColor(red: 147/255, green: 161/255, blue: 161/255, alpha: 1.0)
        }
    }
    
    public var typeColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemBlue
        } else {
            return UIColor(red: 102/255, green: 217/255, blue: 239/255, alpha: 1.0)
        }
    }
    
    public var functionColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemIndigo
        } else {
            return UIColor(red: 111/255, green: 66/255, blue: 193/255, alpha: 1.0)
        }
    }
    
    public var propertyColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemPurple
        } else {
            return UIColor(red: 174/255, green: 129/255, blue: 255/255, alpha: 1.0)
        }
    }
    
    public var operatorColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemRed
        } else {
            return UIColor(red: 249/255, green: 38/255, blue: 114/255, alpha: 1.0)
        }
    }
    
    public var identifierColor: UIColor {
        if #available(iOS 13.0, *) {
            return .label
        } else {
            return .black
        }
    }
    
    public var punctuationColor: UIColor {
        if #available(iOS 13.0, *) {
            return .systemGray
        } else {
            return UIColor(red: 147/255, green: 161/255, blue: 161/255, alpha: 1.0)
        }
    }
    
    public init() {}
}

// MARK: - Dark Theme Implementation
public struct DarkCodeHighlightTheme: CodeHighlightTheme {
    public var font: UIFont = .monospacedSystemFont(ofSize: 14, weight: .regular)
    public var defaultColor: UIColor = .white
    public var backgroundColor: UIColor = UIColor(red: 30/255, green: 30/255, blue: 30/255, alpha: 1.0)
    public var keywordColor: UIColor = UIColor(red: 249/255, green: 38/255, blue: 114/255, alpha: 1.0)
    public var stringColor: UIColor = UIColor(red: 166/255, green: 226/255, blue: 46/255, alpha: 1.0)
    public var numberColor: UIColor = UIColor(red: 253/255, green: 151/255, blue: 31/255, alpha: 1.0)
    public var commentColor: UIColor = UIColor(red: 117/255, green: 113/255, blue: 94/255, alpha: 1.0)
    public var typeColor: UIColor = UIColor(red: 102/255, green: 217/255, blue: 239/255, alpha: 1.0)
    public var functionColor: UIColor = UIColor(red: 111/255, green: 66/255, blue: 193/255, alpha: 1.0)
    public var propertyColor: UIColor = UIColor(red: 174/255, green: 129/255, blue: 255/255, alpha: 1.0)
    public var operatorColor: UIColor = UIColor(red: 249/255, green: 38/255, blue: 114/255, alpha: 1.0)
    public var identifierColor: UIColor = .white
    public var punctuationColor: UIColor = UIColor(red: 147/255, green: 161/255, blue: 161/255, alpha: 1.0)
    
    public init() {}
}

// MARK: - GitHub Theme Implementation
public struct GitHubCodeHighlightTheme: CodeHighlightTheme {
    public var font: UIFont = .monospacedSystemFont(ofSize: 14, weight: .regular)
    public var defaultColor: UIColor = UIColor(red: 36/255, green: 41/255, blue: 46/255, alpha: 1.0)
    public var backgroundColor: UIColor = UIColor(red: 246/255, green: 248/255, blue: 250/255, alpha: 1.0)
    public var keywordColor: UIColor = UIColor(red: 215/255, green: 58/255, blue: 73/255, alpha: 1.0)
    public var stringColor: UIColor = UIColor(red: 3/255, green: 47/255, blue: 98/255, alpha: 1.0)
    public var numberColor: UIColor = UIColor(red: 0/255, green: 92/255, blue: 197/255, alpha: 1.0)
    public var commentColor: UIColor = UIColor(red: 106/255, green: 115/255, blue: 125/255, alpha: 1.0)
    public var typeColor: UIColor = UIColor(red: 111/255, green: 66/255, blue: 193/255, alpha: 1.0)
    public var functionColor: UIColor = UIColor(red: 111/255, green: 66/255, blue: 193/255, alpha: 1.0)
    public var propertyColor: UIColor = UIColor(red: 0/255, green: 92/255, blue: 197/255, alpha: 1.0)
    public var operatorColor: UIColor = UIColor(red: 215/255, green: 58/255, blue: 73/255, alpha: 1.0)
    public var identifierColor: UIColor = UIColor(red: 36/255, green: 41/255, blue: 46/255, alpha: 1.0)
    public var punctuationColor: UIColor = UIColor(red: 106/255, green: 115/255, blue: 125/255, alpha: 1.0)
    
    public init() {}
}

// MARK: - Xcode Theme Implementation
public struct XcodeCodeHighlightTheme: CodeHighlightTheme {
    public var font: UIFont = .monospacedSystemFont(ofSize: 14, weight: .regular)
    public var defaultColor: UIColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)
    public var backgroundColor: UIColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0)
    public var keywordColor: UIColor = UIColor(red: 155/255, green: 35/255, blue: 147/255, alpha: 1.0)
    public var stringColor: UIColor = UIColor(red: 196/255, green: 26/255, blue: 22/255, alpha: 1.0)
    public var numberColor: UIColor = UIColor(red: 28/255, green: 0/255, blue: 207/255, alpha: 1.0)
    public var commentColor: UIColor = UIColor(red: 0/255, green: 116/255, blue: 0/255, alpha: 1.0)
    public var typeColor: UIColor = UIColor(red: 92/255, green: 38/255, blue: 153/255, alpha: 1.0)
    public var functionColor: UIColor = UIColor(red: 50/255, green: 109/255, blue: 116/255, alpha: 1.0)
    public var propertyColor: UIColor = UIColor(red: 92/255, green: 38/255, blue: 153/255, alpha: 1.0)
    public var operatorColor: UIColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)
    public var identifierColor: UIColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)
    public var punctuationColor: UIColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)
    
    public init() {}
} 
